/*
 * The MIT License
 *
 * Copyright 2012 Anonymous.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package pentomino.ui;

import java.awt.*;
import javax.swing.JPanel;
import pentomino.logic.Figure;

/**
 *
 * Represents a user control that shows the game figure state.
 */
public class FigurePanel extends JPanel {
    
    private Figure figure;
    private boolean pressed;
    
    /*============== Constructors ==============*/
    
    /**
     * Creates an instance of the FigurePanel class by default.
     */
    public FigurePanel()
    {
        this(null);
    }
    
    /**
     * Creates an instance of the FigurePanel class with a specified data.
     * 
     * @param source
     * @param active 
     */
    public FigurePanel(Figure source)
    {
        this.figure = source;
        this.pressed = false;
    }
    
    /*============== Member access ==============*/
    
    /**
     * Sets a panel pressed state.
     * 
     * @param value a panel new pressed state
     */
    public void setPressed(boolean value)
    {
        if (pressed != value && isEnabled())
        {
            pressed = value;
            repaint();
        }
    }
    
    /**
     * Gets a panel pressed state information.
     * 
     * @return boolean value that indicates a pressed state 
     */
    public boolean isPressed()
    {
        return pressed;
    }
    
    /**
     * Gets a contained figure object.
     * 
     * @return a game figure
     */
    public Figure getFigure()
    {
        return figure;
    }
    
    /*============== Methods ==============*/
    
    /**
     * Sets the control enabled state.
     * 
     * @param value a new enabled state 
     */
    @Override
    public void setEnabled(boolean value)
    {
        this.setPressed(false);
        super.setEnabled(value);
    }
    
    /**
     * Draws a panel content.
     * 
     * @param g the Graphics context in which to paint
     */
    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        
        if (figure != null)
        {
            Color figureColor;
            Color borderColor = InterfaceHelper.BORDER_COLOR;
            
            if (isEnabled())
                figureColor = InterfaceHelper.getFigureColor(figure);
            else
                figureColor = InterfaceHelper.INVALID_COLOR;
                        
            // Calculates the figure element dimensions:
            
            int pwidth = getWidth();
            int pheight = getHeight();
            
            int md = pwidth < pheight ? pwidth : pheight;
            
            md -= 10; // Min dimension - padding;
            
            // Return if we can't draw a figure with the current size of the panel:
            if (md < figure.getRows() * 2 || md < figure.getColumns() * 2)
                return;

            Rectangle rect = new Rectangle(pwidth / 2 - md / 2, 
                                           pheight / 2 - md / 2,
                                           md / figure.getColumns(),
                                           md / figure.getRows());
            
            Color c = g.getColor();

            for (int i = 0; i < figure.getRows(); i++)
            {
                rect.x = pwidth / 2 - md / 2;
                
                for (int j = 0; j < figure.getColumns(); j++)
                {
                    byte b = figure.bitAt(i, j);
                    
                    if (b == 1)
                    {                        
                        g.setColor(figureColor);
                        g.fillRect(rect.x, rect.y, rect.width, rect.height);
                        g.setColor(borderColor);
                        g.drawRect(rect.x, rect.y, rect.width, rect.height);
                    }
                    
                    rect.x += rect.width;
                }
                
                rect.y += rect.height;
            }
            
            /* Drawing a selection. */
            
            if (pressed)
            {
                Graphics2D g2d = (Graphics2D)g;
                
                rect = new Rectangle(0, 0, pwidth, pheight);
                rect.grow(-2, -2);
                
                GradientPaint gradient = new GradientPaint(rect.x, rect.y, Color.WHITE, 
                                                           rect.x, rect.y + rect.height, InterfaceHelper.SELECTION_COLOR);
                
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f));
                g2d.setPaint(gradient);
                g2d.fillRoundRect(rect.x, rect.y, rect.width, rect.height, 10, 10);
                g2d.setColor(InterfaceHelper.SELECTION_BORDER_COLOR);
                g2d.drawRoundRect(rect.x, rect.y, rect.width, rect.height, 10, 10);
            }
            
            g.setColor(c);
        }
    }
}
